package org.base23.video.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.base23.video.domain.convertor.AiGuidanceConvertor;
import org.base23.video.domain.dto.*;
import org.base23.video.domain.entity.AiGuidanceConversationEntity;
import org.base23.video.domain.entity.AiGuidanceMessageEntity;
import org.base23.video.repository.AiGuidanceConversationRepository;
import org.base23.video.repository.AiGuidanceMessageRepository;
import org.base23.video.service.AiGuidanceService;
import org.base23.video.service.VideoAnalysisApiService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 基于数据库的AI指导服务实现
 */
@Service
@Primary
@RequiredArgsConstructor
@Slf4j
public class DatabaseAiGuidanceServiceImpl implements AiGuidanceService {
    
    private final ChatClient.Builder chatClientBuilder;
    private final VectorStore vectorStore;
    private final VideoAnalysisApiService videoAnalysisApiService;
    private final AiGuidanceConversationRepository conversationRepository;
    private final AiGuidanceMessageRepository messageRepository;
    
    private ChatClient chatClient;

    @Override
    @Transactional
    public AiGuidanceConversation createConversation(String resultId, String sportType, String userId) {
        log.info("创建AI指导会话，结果ID: {}, 运动类型: {}, 用户ID: {}", resultId, sportType, userId);
        
        try {
            // 先检查是否已存在对应的活跃会话
            AiGuidanceConversationEntity existingConversation = conversationRepository.findActiveConversationByResultIdAndUserId(resultId, userId);
            if (existingConversation != null) {
                log.info("已存在活跃会话，直接返回，会话ID: {}", existingConversation.getId());
                
                // 转换为DTO并返回
                AiGuidanceConversation conversation = AiGuidanceConvertor.toDto(existingConversation);
                List<AiGuidanceMessageEntity> messageEntities = messageRepository.findByConversationIdOrderBySequence(existingConversation.getId());
                conversation.setMessages(AiGuidanceConvertor.toMessageDtoList(messageEntities));
                
                return conversation;
            }
            
            // 创建新会话实体
            AiGuidanceConversationEntity conversationEntity = new AiGuidanceConversationEntity();
            // ID由MyBatis Plus自动生成，不需要手动设置
            conversationEntity.setUserId(userId);
            conversationEntity.setSportType(sportType);
            conversationEntity.setResultId(resultId);
            conversationEntity.setStatus(AiGuidanceConversationEntity.ConversationStatus.ACTIVE.getCode());
            conversationEntity.setMessageCount(0);
            conversationEntity.setTitle("AI运动指导 - " + sportType);
            
            // 获取分析结果概要
            try {
                VideoAnalysisResult.VideoAnalysisData analysisData = videoAnalysisApiService.getAnalysisResult(resultId);
                String summary = generateAnalysisSummary(analysisData, sportType);
                conversationEntity.setContextSummary(summary);
            } catch (Exception e) {
                log.warn("获取分析结果失败: {}", e.getMessage());
                conversationEntity.setContextSummary("运动分析会话");
            }
            
            // 保存会话到数据库
            boolean saved = conversationRepository.saveConversation(conversationEntity);
            if (!saved) {
                throw new RuntimeException("会话保存失败");
            }
            
            log.info("会话保存成功，ID: {}", conversationEntity.getId());
            
            // 验证会话是否真的保存成功
            AiGuidanceConversationEntity savedConversation = conversationRepository.findById(conversationEntity.getId());
            if (savedConversation == null) {
                throw new RuntimeException("会话保存后查询失败，ID: " + conversationEntity.getId());
            }
            
            // 添加欢迎消息
            AiGuidanceMessageEntity welcomeMessageEntity = new AiGuidanceMessageEntity();
            // ID由MyBatis Plus自动生成，不需要手动设置
            welcomeMessageEntity.setConversationId(conversationEntity.getId());
            welcomeMessageEntity.setSender(AiGuidanceMessageEntity.MessageSender.AI.getCode());
            welcomeMessageEntity.setContent(generateWelcomeMessage(sportType));
            welcomeMessageEntity.setMessageType(AiGuidanceMessageEntity.MessageType.TEXT.getCode());
            welcomeMessageEntity.setSequenceNumber(1);
            
            log.info("准备保存欢迎消息，会话ID: {}", conversationEntity.getId());
            
            // 保存欢迎消息到数据库
            boolean messageSaved = messageRepository.saveMessage(welcomeMessageEntity);
            if (!messageSaved) {
                throw new RuntimeException("欢迎消息保存失败");
            }
            
            log.info("欢迎消息保存成功");
            
            // 更新会话消息数量
            conversationRepository.updateMessageCount(conversationEntity.getId(), 1);
            
            // 转换为DTO并返回
            AiGuidanceConversation conversation = AiGuidanceConvertor.toDto(conversationEntity);
            List<AiGuidanceMessageEntity> messageEntities = messageRepository.findByConversationIdOrderBySequence(conversationEntity.getId());
            conversation.setMessages(AiGuidanceConvertor.toMessageDtoList(messageEntities));
            
            log.info("AI指导会话创建成功，会话ID: {}", conversationEntity.getId());
            return conversation;
            
        } catch (Exception e) {
            log.error("创建AI指导会话失败：", e);
            throw new RuntimeException("创建AI指导会话失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional
    public AiGuidanceResponse askQuestion(AiGuidanceRequest request) {
        log.info("处理AI指导问题，会话ID: {}, 问题: {}", request.getConversationId(), request.getQuestion());
        
        // 获取会话
        AiGuidanceConversationEntity conversationEntity = conversationRepository.findById(request.getConversationId());
        if (conversationEntity == null) {
            throw new RuntimeException("会话不存在: " + request.getConversationId());
        }
        
        // 获取当前最大序列号
        Integer maxSequence = messageRepository.getMaxSequenceByConversationId(conversationEntity.getId());
        if (maxSequence == null) maxSequence = 0;
        
        // 添加用户消息
        AiGuidanceMessageEntity userMessageEntity = new AiGuidanceMessageEntity();
        // ID由MyBatis Plus自动生成，不需要手动设置
        userMessageEntity.setConversationId(conversationEntity.getId());
        userMessageEntity.setSender(AiGuidanceMessageEntity.MessageSender.USER.getCode());
        userMessageEntity.setContent(request.getQuestion());
        userMessageEntity.setMessageType(AiGuidanceMessageEntity.MessageType.TEXT.getCode());
        userMessageEntity.setSequenceNumber(maxSequence + 1);
        messageRepository.saveMessage(userMessageEntity);
        
        // 生成AI回复
        String aiResponse = generateAiResponseString(conversationEntity, request);
        
        // 添加AI回复消息
        AiGuidanceMessageEntity aiMessageEntity = new AiGuidanceMessageEntity();
        // ID由MyBatis Plus自动生成，不需要手动设置
        aiMessageEntity.setConversationId(conversationEntity.getId());
        aiMessageEntity.setSender(AiGuidanceMessageEntity.MessageSender.AI.getCode());
        aiMessageEntity.setContent(aiResponse);
        aiMessageEntity.setMessageType(AiGuidanceMessageEntity.MessageType.TEXT.getCode());
        aiMessageEntity.setSequenceNumber(maxSequence + 2);
        messageRepository.saveMessage(aiMessageEntity);
        
        // 更新会话消息数量
        Integer messageCount = messageRepository.countByConversationId(conversationEntity.getId());
        conversationRepository.updateMessageCount(conversationEntity.getId(), messageCount);
        
        // 构建响应
        AiGuidanceResponse response = new AiGuidanceResponse();
        response.setConversationId(request.getConversationId());
        response.setAiResponse(aiResponse);
        response.setSuggestedQuestions(generateSuggestedQuestions(conversationEntity.getSportType()));
        
        log.info("AI指导响应生成完成，会话ID: {}", request.getConversationId());
        return response;
    }

    @Override
    public AiGuidanceConversation getConversation(String conversationId) {
        AiGuidanceConversationEntity conversationEntity = conversationRepository.findById(conversationId);
        if (conversationEntity == null) {
            return null;
        }
        
        List<AiGuidanceMessageEntity> messageEntities = messageRepository.findByConversationIdOrderBySequence(conversationId);
        
        AiGuidanceConversation conversation = AiGuidanceConvertor.toDto(conversationEntity);
        conversation.setMessages(AiGuidanceConvertor.toMessageDtoList(messageEntities));
        
        return conversation;
    }

    @Override
    public List<AiGuidanceConversation> getUserConversations(String resultId) {
        // 根据resultId查询对应的会话列表
        LambdaQueryWrapper<AiGuidanceConversationEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AiGuidanceConversationEntity::getResultId, resultId)
               .orderByDesc(AiGuidanceConversationEntity::getLastUpdateTime);
        
        List<AiGuidanceConversationEntity> entities = conversationRepository.list(wrapper);
        return AiGuidanceConvertor.toDtoList(entities);
    }

    @Override
    public void endConversation(String conversationId) {
        conversationRepository.endConversation(conversationId);
        log.info("会话已结束: {}", conversationId);
    }

    @Override
    public void cleanupExpiredConversations() {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(7);
        int deletedCount = conversationRepository.deleteExpiredConversations(expireTime);
        log.info("清理过期会话完成，删除数量: {}", deletedCount);
    }

    /**
     * 生成分析摘要
     */
    private String generateAnalysisSummary(VideoAnalysisResult.VideoAnalysisData analysisData, String sportType) {
        return String.format("您的%s运动分析已完成，AI助手将为您提供专业的技术指导和改进建议。", sportType);
    }

    /**
     * 生成欢迎消息
     */
    private String generateWelcomeMessage(String sportType) {
        return String.format("您好！我是您的YOMI AI教练。我已经分析了您的运动视频，准备为您提供专业的技术指导。请告诉我您想了解什么？", sportType);
    }

    /**
     * 生成AI回复
     */
    private String generateAiResponseString(AiGuidanceConversationEntity conversation, AiGuidanceRequest request) {
        try {
            if (chatClient == null) {
                chatClient = chatClientBuilder.build();
            }
            
            // 构建上下文
            StringBuilder context = new StringBuilder();
            context.append("运动类型: ").append(conversation.getSportType()).append("\n");
            context.append("会话摘要: ").append(conversation.getContextSummary()).append("\n");
            
            // 获取最近的几条消息作为上下文
            List<AiGuidanceMessageEntity> recentMessages = messageRepository.findRecentMessages(conversation.getId(), 5);
            if (!recentMessages.isEmpty()) {
                context.append("对话历史:\n");
                for (AiGuidanceMessageEntity msg : recentMessages) {
                    String sender = "AI".equals(msg.getSender()) ? "教练" : "学员";
                    context.append(sender).append(": ").append(msg.getContent()).append("\n");
                }
            }
            
            String prompt = String.format(
                "你是一个专业的%s教练，基于以下上下文回答学员的问题：\n\n%s\n\n学员问题：%s\n\n请提供专业、准确、有帮助的回答。",
                conversation.getSportType(), context.toString(), request.getQuestion()
            );
            
            return chatClient.prompt()
                .user(prompt)
                .call()
                .content();
                
        } catch (Exception e) {
            log.error("生成AI回复失败: {}", e.getMessage(), e);
            return "抱歉，我现在无法回答您的问题。请稍后再试。";
        }
    }

    @Override
    public List<String> generateSuggestedQuestions(String conversationId, String sportType) {
        List<String> questions = new ArrayList<>();
        switch (sportType.toLowerCase()) {
            case "basketball":
                questions.add("如何提高投篮准确率？");
                questions.add("运球技巧有什么改进建议？");
                questions.add("防守时应该注意什么？");
                break;
            case "football":
                questions.add("如何提高传球精度？");
                questions.add("射门技巧有什么建议？");
                questions.add("跑位时机如何把握？");
                break;
            default:
                questions.add("我的动作哪里需要改进？");
                questions.add("如何提高技术水平？");
                questions.add("有什么训练建议？");
        }
        return questions;
    }

    /**
     * 生成推荐问题（内部方法）
     */
    private List<String> generateSuggestedQuestions(String sportType) {
        return generateSuggestedQuestions(null, sportType);
    }
} 